package com.yiquan.chat.netty;

import com.alibaba.fastjson.JSON;
import com.yiquan.chat.SpringUtil;
import com.yiquan.chat.client.UserClient;
import com.yiquan.chat.dao.ActivityDao;
import com.yiquan.chat.dao.ConverseDao;
import com.yiquan.chat.dao.MessageDao;
import com.yiquan.chat.pojo.*;
import com.yiquan.chat.service.ConverseService;
import com.yiquan.chat.service.MessageService;
import entity.Result;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import util.IdWorker;
import util.ObjectUtils;

import java.util.*;

/**
 * @author Tyrone
 * @date 2021/12/28 1:42
 */
@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    /**
     * 将所有与客户端连接的Channel交给ChannelGroup管理
     * 表示当前服务器内所有在线的用户的channel
     */
    private static ChannelGroup users = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        MessageDao messageDao = (MessageDao) SpringUtil.getBean(MessageDao.class);
        MessageService messageService = (MessageService) SpringUtil.getBean(MessageService.class);


        /**
         * 获取消息内容
         */
        String content = msg.text();

        /**
         * 当前频道
         */
        Channel currentChannel = ctx.channel();

        DataContent dataContent = JSON.parseObject(content, DataContent.class);
        log.info("收到信息：",dataContent);

        Integer action = dataContent.getAction();

        if (action == MsgActionEnum.CONNECT.type) {

            Long connectServerUserId = dataContent.getMessage().getFrom_user_id();
            log.info("用户：{} 接入服务器", connectServerUserId);
            UserChannelRel.put(connectServerUserId, currentChannel);
        } else if (action == MsgActionEnum.CHAT.type) {
            log.info("收到消息：{}", dataContent);
            Message message = getMessage(dataContent);
            DataContent dataContentMsg = new DataContent();
            dataContentMsg.setMessage(message);
            Channel receiverChannel = UserChannelRel.get(message.getTo_user_id());
            if (receiverChannel == null) {
                // TODO: 2021/12/28 消息接收方不在线，采取消息推送的形式 
            } else {
                Channel findChannel = users.find(receiverChannel.id());
                if (findChannel != null) {
                    // TODO: 2021/12/28  findChannel 不为空代表当前用户在线 
                    receiverChannel.writeAndFlush(new TextWebSocketFrame(
                            JSON.toJSONString(dataContentMsg))
                    );
                } else {
                    // TODO: 2021/12/28  用户离线 消息推送
                }
            }
        } else if (action == MsgActionEnum.SIGNED.type) {
            String msgIdsStr = dataContent.getExtend();
            String[] idsStr = msgIdsStr.split(",");
            List<Long> msgIds = new ArrayList<>();
            for (String s : idsStr) {
                msgIds.add(Long.parseLong(s));
            }
            if (msgIds != null && !msgIds.isEmpty() && msgIds.size() > 0) {
                // TODO: 2021/7/6  更新签收状态
                messageService.updateMessageListByMsgId(msgIds, MessageService.MSG_STATE_SIGN);
            }
        } else if (action == MsgActionEnum.KEEPALIVE.type) {
            System.out.println("收到来自channel为[" + currentChannel + "]的心跳包...");

        } else if (action == MsgActionEnum.FOLLOW.type) {

        }

    }

    private Message getMessage(DataContent dataContent) {
        IdWorker idWorker = SpringUtil.getBean(IdWorker.class);
        MessageDao messageDao = SpringUtil.getBean(MessageDao.class);
        ConverseDao converseDao = SpringUtil.getBean(ConverseDao.class);
        ConverseService converseService = SpringUtil.getBean(ConverseService.class);
        Message message = dataContent.getMessage();
        Integer msgType = dataContent.getExtend().equals("image")?2:1;
        Long fromUserId = message.getFrom_user_id();
        Long toUserId = message.getTo_user_id();
        // 调用user服务获取用户相关信息
        UserClient userClient = SpringUtil.getBean(UserClient.class);
        LinkedHashMap<String, Object> fromUserData = (LinkedHashMap<String, Object>) userClient.findByUserId(fromUserId).getData();
        LinkedHashMap<String, Object> toUserData = (LinkedHashMap<String, Object>) userClient.findByUserId(toUserId).getData();
        User from = User.builder()
                .user_id(fromUserId)
                .nick_name((String) fromUserData.get("nick_name"))
                .avatar((String) fromUserData.get("avatar")).build();
        User to = User.builder()
                .user_id(toUserId)
                .nick_name((String) toUserData.get("nick_name"))
                .avatar((String) toUserData.get("avatar")).build();
        //获取对方和我的会话id,没有创建
        Long toUserConverseId = converseService.addOrGetConverse(toUserId, fromUserId);
        Long converseId = converseService.addOrGetConverse(fromUserId, toUserId);
        Message toUserConverseMsg = new Message();
        message.setMsg_id(converseService.getUniqueId());
        message.setFrom_user_id(from.getUser_id());
        message.setTo_user_id(to.getUser_id());
        message.setMsg_state(MessageService.MSG_STATE_SEND + "");
        message.setMsgSendDate(new Date());
        message.setCreate_date(new Date());
        message.setMsg_state("0");
        message.setMsg_type(msgType);
        ObjectUtils.copyPropertiesIgnoreNull(message, toUserConverseMsg);
        toUserConverseMsg.setConverse_id(toUserConverseId);
        message.setConverse_id(converseId);
        messageDao.save(toUserConverseMsg);
        message = messageDao.save(message);
        return message;
    }

    private Message getSystemInfo(DataContent dataContent) {
        ActivityDao activityDao = SpringUtil.getBean(ActivityDao.class);
        Message message = dataContent.getMessage();
        Activity activity = new Activity();
        activity.setAction(dataContent.getAction());
        activity.setFrom_user_id(message.getFrom_user_id());
        activity.setTo_user_id(message.getTo_user_id());
        activity.setStatus(0);
        activityDao.save(activity);
        return null;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        users.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {

        users.remove(ctx.channel());
        super.handlerRemoved(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.channel().close();
        users.remove(ctx.channel());
    }


    public void initSystemMsgMaster() {

    }

}
